package com.cloudweb.oa.utils;

import com.cloudwebsoft.framework.util.LogUtil;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;

@Component
public class XmlUtil {

    /**
     * 解析微信XML
     * @return
     */
    public HashMap<String, String> parseXml(String contentXml) {
        HashMap<String,String> hashMap = new HashMap<>();

        try {
            // 检查是否包含DOCTYPE或ENTITY声明，以免产生 XEE 漏洞
            if (contentXml.matches("(?s)<!DOCTYPE.*?>") || contentXml.matches("(?s)<!ENTITY.*?>")) {
                throw new DocumentException("不安全的XML内容: 包含DOCTYPE或ENTITY声明");
            }
            Document document = DocumentHelper.parseText(contentXml);
            Element root = document.getRootElement();
            List<Element> list = root.elements();
            for (Element e : list) {
                hashMap.put(e.getName(),e.getText());
            }
        } catch (DocumentException e) {
            LogUtil.getLog(getClass()).error(e);
        }

        /*
        // 另一种安全的方法
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
            factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
            factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
            DocumentBuilder db = factory.newDocumentBuilder();

            StringReader sr = new StringReader(contentXml);
            InputSource is = new InputSource(sr);
            org.w3c.dom.Document doc = db.parse(is);
            org.w3c.dom.Element root = doc.getDocumentElement();
            NodeList list = root.getChildNodes();
            for(int i=0;i<list.getLength();i++){
                Node node = list.item(i);
                hashMap.put(node.getNodeName(), node.getNodeValue());
            }
        } catch (IOException | ParserConfigurationException | SAXException e) {
            LogUtil.getLog(getClass()).error(e);
        }*/

        return hashMap;
    }

}
